package com.zsqat.common.valid;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

// 自定义注解的定义
@Documented
// 是最关键的，它表示这个注解是一个验证注解，并且指定了一个实现验证逻辑的验证器
@Constraint(validatedBy = { ListValueConstraintValidator.class })
// 指明这个注解要作用在什么地方，可以是对象、域、构造器等
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
/*
 * 指明了注解的生命周期，可以有SOURCE（仅保存在源码中，会被编译器丢弃），
 * CLASS（在class文件中可用，会被VM丢弃），
 * RUNTIME（在运行期也被保留），
 * 这里选择了生命周期最长的RUNTIME
*/
@Retention(RUNTIME)
public @interface ListValue {
  // 指明了验证失败后返回的消息，消息定义在 resources\ValidationMessages.properties
  String message() default "{com.zsqat.common.valid.ListValue.message}";

  // 约束注解在验证时所属的组别
  Class<?>[] groups() default { };

  // 约束注解的有效负载,有效负载通常用来将一些元数据信息与该约束注解相关联，
  // 常用的一种情况是用负载表示验证结果的严重程度。
  Class<? extends Payload>[] payload() default { };

  // 自定义参数范围，便于验证实例进行判断使用
  int[] vals() default { };
}

/*
  自定义注解中声明的方法返回类型必须是以下其一，不然编译会出错:

  invalid type of annotation member。下面分别对以上几种类型作个简单的描述：

  1. A primitive type ： 基本类型(java的八种基本类型：byte、short、int、long、float、double、char、boolean)

  2. String ： 字符串

  3. Class ：Class

  4. An enum type ： 枚举

  5. An annotation type ：注解

  6. An array type ：类型为以上任一类型的数组
*/